#include "VirtualNDK.h"
#include "Modules.h"
#include <queue>
#include "public.h"
#include <stdio.h>
#include "VMemory.h"
#include "config.h"
#include "Module.h"
#include "Hooker.h"
#include "NativeHooks.h"
#include "Trace.h"
VirtualNDK::VirtualNDK()
{
	uc_err err;
	modules = new Modules(this);
	vmem = new VMemory(this);
	
	err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc);
	if (err)
	{
		logger("Failed on uc_open() with error returned: %u (%s)\n", err, uc_strerror(err));
	}
	uc_mem_map(uc, STACK_ADDR, STACK_SIZE, UC_PROT_ALL);
	uint32_t stack = STACK_ADDR + STACK_SIZE;
	uc_reg_write(uc, UC_ARM_REG_SP, &stack);

	//hook
	uc_mem_map(uc, HOOK_MEMORY_BASE, HOOK_MEMORY_SIZE, UC_PROT_ALL);
	hooker = new Hooker(this, HOOK_MEMORY_BASE, HOOK_MEMORY_SIZE);
	native_hooks= new NativeHooks(this,hooker);

	trace = new Trace(uc);
}

VirtualNDK::~VirtualNDK()
{
	delete modules;
	delete vmem;
	delete hooker;
	delete native_hooks;
	delete trace;
}

Module * VirtualNDK::load_library(char * filename, bool do_init)
{
	Module* libmod = modules->load_module(filename);

	if (do_init)
	{

	}
	return libmod;
}

void VirtualNDK::call_symbol(Module * module, std::string symbol_name, int argc, char * argv[])
{
	SymbolResolved* symbol = module->find_symbol(symbol_name);
	if (symbol == nullptr)
	{
		logger("Unable to find symbol \'%s\' in module \'%s\'.", symbol_name, module->filename);
		return;
	}
	call_native(symbol->address, argc,argv);
}

void VirtualNDK::call_native(uint64_t addr, int argc, char * argv[])
{
	uc_err err;
	bool is_jni = false;

	if (argc >= 1)
	{

	}
	uint32_t a1 = 5;
	uc_reg_write(uc, UC_ARM_REG_R0, &a1);
	/*a1 = 0x55AA7665;
	uc_reg_write(uc, UC_ARM_REG_R1, &a1);*/

	uint64_t stop_pos = HOOK_MEMORY_BASE | 1;

	uc_reg_write(uc, UC_ARM_REG_LR, &stop_pos);
	err = uc_emu_start(uc, addr, stop_pos - 1, 0, 0);
	if (UC_ERR_OK != err)
	{
		logger("error: %u (%s)\n", err, uc_strerror(err));
	}
}




